////////////////////////////////////////
// EECE478 COMPUTER GRAPHICS
// Spring term 2011
// Assignment 1 Model Rendering
// (Tim) Wei-Ting Liu
// #29144052
////////////////////////////////////////

#include "loadModel.h"

using namespace std;

vector<float> loadCoor3d(string *pt){
	vector<float> coor;
	string tmp;
	for(int i=0; i<3; i++){
		tmp = *(pt+i);
		coor.push_back(atof(tmp.c_str()));
	}
 
	//return coorThreeD;
	return coor;
}

// Reads and parses lines
loadModel::loadModel(string target){
	ifstream inFile(target, ios::binary);
	if(inFile.is_open()){
		int counter = 0;
		while(inFile.good()){
			string line;
			getline(inFile, line);
			vector<string> subString;
			string buffer;
			stringstream sStream(line);

			while(sStream >> buffer){
				subString.push_back(buffer);
			}
			if(subString.size() != 0){
				string tag = subString[0].substr(0,1);
				string tmpStr;
				switch(tag[0]){
				case 'b':
				case 'B':
					// Building name
					for(int i=1; i<subString.size(); i++)
						buildingName = buildingName + subString[i] + " ";
					break;
				case 'i':
				case 'I':
					// Texture file name
					for(int i=1; i<subString.size(); i++)
						tmpStr = tmpStr + subString[i] + " ";
					texture.push_back(tmpStr);
					break;
				case 'v':
				case 'V':
					// Model vertices
					if(subString.size() != 4)
						cout << "Vertex at line [" << counter << "] does not have 3 numbers." << endl;
					vertex.push_back(loadCoor3d(&subString[1]));
					break;
				case 'n':
				case 'N':
					// Model normals
					if(subString.size() != 4)
						cout << "Normal at line [" << counter << "] does not have 3 numbers." << endl;
					normal.push_back(loadCoor3d(&subString[1]));
					break;
				case 't':
				case 'T':
					// Model triangles
					try{
						triangleSet.push_back(loadTriangle(subString));
					}catch(const char* str){
						cout << "Triangle at line [" << counter << "]" <<  str << endl;
					}
					break;
				}
			}
			counter++;
		}
		inFile.close();
	}else{
		cout << "Unable to open model file: " << target << endl;
		exit(1);
	}
}

string loadModel::getBuildingName(){ return buildingName; }
vector<string> loadModel::getTexture(){ return texture; }
vector<vector<float>> loadModel::getVertex(){ return vertex; }
vector<vector<float>> loadModel::getNormal(){ return normal; }
vector<triangle> loadModel::getTriangle(){ return triangleSet; }

loadModel::~loadModel(){}

// Triangles that make up the scene
triangle loadTriangle(vector<string> str){
	triangle tri;
	if(str.size() == 12){
		vector<vector<float>> textcoor;
		vector<float>coor;
		for(int i=1; i<str.size(); i++){
			if(i>=1 && i<=3)
				tri.vertex.push_back(atoi(str[i].c_str()));
			if(i==4)
				tri.normal = atoi(str[i].c_str());
			if(i==5)
				tri.texture = atoi(str[i].c_str());
			if(i>5){
				if(i%2==0){
					coor.clear();
					coor.push_back(atof(str[i].c_str()));
				}else{
					coor.push_back(atof(str[i].c_str()));
					textcoor.push_back(coor);
				}
			}
		}
		tri.textureCoordinate = textcoor;
		
		return tri;
	}else{
		throw "does not have 12 elements.";
	}
}